package org.naxx.security.parser.validation.impl;

import java.io.File;
import java.io.InputStream;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.naxx.security.common.Configurable;
import org.naxx.security.parser.validation.SchemaValidator;
import org.naxx.security.util.Assert;
import org.xml.sax.SAXException;

public final class SchemaValidatorImpl implements SchemaValidator, Configurable {

	/*
	 * We imported policy schema into context schema so we treat it as single
	 * schema. TODO investigate this, is this anti-pattern?
	 */
	private String schemaLocation;
	private SchemaFactory factory;
	private Schema xacmlSchema;
	
	public void setSchemaLocation(String schemaLocation) {
		this.schemaLocation = schemaLocation;
	}

	public void configure() {
		this.factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		try {
			File file = new File(this.schemaLocation);
			Assert.assertFileExistsAndReadable(file);
			this.xacmlSchema = this.factory.newSchema(new StreamSource(file));
		} catch (SAXException e) {
			throw new IllegalStateException("Unable to create schema factory", e);
		}
	}

	public void validate(InputStream xmlStream) throws Exception {
		this.xacmlSchema.newValidator().validate(new StreamSource(xmlStream));
	}

	public void validate(File file) throws Exception {
		this.xacmlSchema.newValidator().validate(new StreamSource(file));
	}
}
